using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;

namespace EntityKit.Runtime
{
    /// <summary>
    /// 文件操作工具类
    /// </summary>
    public static class FileHelper
    {
        #region 路径操作

        /// <summary>
        /// 组合路径（自动处理路径分隔符）
        /// </summary>
        public static string CombinePath(params string[] paths)
        {
            if (paths == null || paths.Length == 0)
                return string.Empty;

            string combinedPath = paths[0];
            for (int i = 1; i < paths.Length; i++)
            {
                combinedPath = Path.Combine(combinedPath, paths[i]);
            }

            return combinedPath;
        }

        /// <summary>
        /// 确保路径以斜杠结尾
        /// </summary>
        public static string EnsurePathEndsWithSlash(string path)
        {
            if (string.IsNullOrEmpty(path))
                return string.Empty;

            char lastChar = path[path.Length - 1];
            if (lastChar != Path.DirectorySeparatorChar && lastChar != Path.AltDirectorySeparatorChar)
            {
                return path + Path.DirectorySeparatorChar;
            }

            return path;
        }

        /// <summary>
        /// 获取文件名（不包含扩展名）
        /// </summary>
        public static string GetFileNameWithoutExtension(string filePath)
        {
            return Path.GetFileNameWithoutExtension(filePath);
        }

        /// <summary>
        /// 获取文件扩展名
        /// </summary>
        public static string GetExtension(string filePath)
        {
            return Path.GetExtension(filePath);
        }

        /// <summary>
        /// 获取文件所在目录
        /// </summary>
        public static string GetDirectoryPath(string filePath)
        {
            return Path.GetDirectoryName(filePath);
        }

        /// <summary>
        /// 将路径中的分隔符统一为正斜杠(/)
        /// </summary>
        public static string NormalizePathToForwardSlash(string path)
        {
            if (string.IsNullOrEmpty(path))
                return path;

            return path.Replace('\\', '/');
        }

        /// <summary>
        /// 将路径中的分隔符统一为反斜杠(\)
        /// </summary>
        public static string NormalizePathToBackwardSlash(string path)
        {
            if (string.IsNullOrEmpty(path))
                return path;

            return path.Replace('/', '\\');
        }

        #endregion

        #region 目录操作

        /// <summary>
        /// 检查目录是否存在
        /// </summary>
        public static bool DirectoryExists(string path)
        {
            return Directory.Exists(path);
        }

        /// <summary>
        /// 创建目录（如果不存在）
        /// </summary>
        public static bool CreateDirectoryIfNotExists(string path)
        {
            if (!DirectoryExists(path))
            {
                try
                {
                    Directory.CreateDirectory(path);
                    return true;
                }
                catch (Exception ex)
                {
                    Debug.LogError($"Failed to create directory {path}: {ex.Message}");
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// 删除目录（包括所有子目录和文件）
        /// </summary>
        public static bool DeleteDirectory(string path, bool recursive = true)
        {
            if (!DirectoryExists(path))
                return true;

            try
            {
                Directory.Delete(path, recursive);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to delete directory {path}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 获取目录中的所有文件
        /// </summary>
        public static string[] GetFiles(string path, string searchPattern = "*", bool recursive = false)
        {
            if (!DirectoryExists(path))
                return new string[0];

            try
            {
                SearchOption option = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
                return Directory.GetFiles(path, searchPattern, option);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to get files from directory {path}: {ex.Message}");
                return Array.Empty<string>();
            }
        }

        /// <summary>
        /// 获取目录中的所有子目录
        /// </summary>
        public static string[] GetDirectories(string path, bool recursive = false)
        {
            if (!DirectoryExists(path))
                return new string[0];

            try
            {
                SearchOption option = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
                return Directory.GetDirectories(path, "*", option);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to get directories from directory {path}: {ex.Message}");
                return new string[0];
            }
        }

        #endregion

        #region 文件操作

        /// <summary>
        /// 检查文件是否存在
        /// </summary>
        public static bool FileExists(string filePath)
        {
            return File.Exists(filePath);
        }

        /// <summary>
        /// 创建文件（如果不存在）
        /// </summary>
        public static bool CreateFileIfNotExists(string filePath)
        {
            if (FileExists(filePath))
                return true;

            try
            {
                // 确保目录存在
                string directory = Path.GetDirectoryName(filePath);
                CreateDirectoryIfNotExists(directory);

                // 创建空文件
                using (File.Create(filePath))
                {
                }

                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to create file {filePath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        public static bool DeleteFile(string filePath)
        {
            if (!FileExists(filePath))
                return true;

            try
            {
                File.Delete(filePath);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to delete file {filePath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 复制文件
        /// </summary>
        public static bool CopyFile(string sourcePath, string destinationPath, bool overwrite = true)
        {
            if (!FileExists(sourcePath))
            {
                Debug.LogError($"Source file does not exist: {sourcePath}");
                return false;
            }

            try
            {
                // 确保目标目录存在
                string directory = Path.GetDirectoryName(destinationPath);
                CreateDirectoryIfNotExists(directory);

                File.Copy(sourcePath, destinationPath, overwrite);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to copy file from {sourcePath} to {destinationPath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 移动文件
        /// </summary>
        public static bool MoveFile(string sourcePath, string destinationPath)
        {
            if (!FileExists(sourcePath))
            {
                Debug.LogError($"Source file does not exist: {sourcePath}");
                return false;
            }

            try
            {
                // 确保目标目录存在
                string directory = Path.GetDirectoryName(destinationPath);
                CreateDirectoryIfNotExists(directory);

                if (FileExists(destinationPath))
                {
                    File.Delete(destinationPath);
                }

                File.Move(sourcePath, destinationPath);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to move file from {sourcePath} to {destinationPath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 获取文件大小（字节）
        /// </summary>
        public static long GetFileSize(string filePath)
        {
            if (!FileExists(filePath))
                return -1;

            try
            {
                return new FileInfo(filePath).Length;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to get file size for {filePath}: {ex.Message}");
                return -1;
            }
        }

        /// <summary>
        /// 获取文件最后写入时间
        /// </summary>
        public static DateTime GetLastWriteTime(string filePath)
        {
            if (!FileExists(filePath))
                return DateTime.MinValue;

            try
            {
                return File.GetLastWriteTime(filePath);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to get last write time for {filePath}: {ex.Message}");
                return DateTime.MinValue;
            }
        }

        #endregion

        #region 文本文件读写

        /// <summary>
        /// 读取文本文件全部内容
        /// </summary>
        public static string ReadTextFile(string filePath)
        {
            if (!FileExists(filePath))
            {
                Debug.LogError($"File does not exist: {filePath}");
                return string.Empty;
            }

            try
            {
                return File.ReadAllText(filePath);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to read text file {filePath}: {ex.Message}");
                return string.Empty;
            }
        }

        /// <summary>
        /// 逐行读取文本文件
        /// </summary>
        public static string[] ReadTextFileLines(string filePath)
        {
            if (!FileExists(filePath))
            {
                Debug.LogError($"File does not exist: {filePath}");
                return new string[0];
            }

            try
            {
                return File.ReadAllLines(filePath);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to read text file lines {filePath}: {ex.Message}");
                return new string[0];
            }
        }

        /// <summary>
        /// 写入文本到文件
        /// </summary>
        public static bool WriteTextFile(string filePath, string content)
        {
            try
            {
                // 确保目录存在
                string directory = Path.GetDirectoryName(filePath);
                CreateDirectoryIfNotExists(directory);
                if (File.Exists(filePath))
                {
                    File.SetAttributes(filePath, FileAttributes.Normal);
                }

                File.WriteAllText(filePath, content);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to write text file {filePath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 追加文本到文件
        /// </summary>
        public static bool AppendTextToFile(string filePath, string content)
        {
            try
            {
                // 确保目录存在
                string directory = Path.GetDirectoryName(filePath);
                CreateDirectoryIfNotExists(directory);

                File.AppendAllText(filePath, content);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to append text to file {filePath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 逐行写入文本到文件
        /// </summary>
        public static bool WriteTextFileLines(string filePath, string[] lines)
        {
            try
            {
                // 确保目录存在
                string directory = Path.GetDirectoryName(filePath);
                CreateDirectoryIfNotExists(directory);

                File.WriteAllLines(filePath, lines);
                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to write text file lines {filePath}: {ex.Message}");
                return false;
            }
        }

        #endregion

        #region 二进制文件读写

        /// <summary>
        /// 写入对象到二进制文件
        /// </summary>
        public static bool WriteBinaryFile<T>(string filePath, T obj)
        {
            try
            {
                // 确保目录存在
                string directory = Path.GetDirectoryName(filePath);
                CreateDirectoryIfNotExists(directory);

                using (FileStream fileStream = File.Create(filePath))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(fileStream, obj);
                }

                return true;
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to write binary file {filePath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 从二进制文件读取对象
        /// </summary>
        public static T ReadBinaryFile<T>(string filePath)
        {
            if (!FileExists(filePath))
            {
                Debug.LogError($"Binary file does not exist: {filePath}");
                return default(T);
            }

            try
            {
                using (FileStream fileStream = File.Open(filePath, FileMode.Open))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    return (T)formatter.Deserialize(fileStream);
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to read binary file {filePath}: {ex.Message}");
                return default(T);
            }
        }

        #endregion

        #region JSON文件读写

        /// <summary>
        /// 写入对象到JSON文件
        /// </summary>
        public static bool WriteJsonFile<T>(string filePath, T obj)
        {
            try
            {
                string json = JsonUtility.ToJson(obj, true);
                return WriteTextFile(filePath, json);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to write JSON file {filePath}: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 从JSON文件读取对象
        /// </summary>
        public static T ReadJsonFile<T>(string filePath)
        {
            string json = ReadTextFile(filePath);
            if (string.IsNullOrEmpty(json))
            {
                return default(T);
            }

            try
            {
                return JsonUtility.FromJson<T>(json);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to read JSON file {filePath}: {ex.Message}");
                return default(T);
            }
        }

        #endregion

        #region 文件信息工具

        /// <summary>
        /// 获取文件信息
        /// </summary>
        public static FileInfo GetFileInfo(string filePath)
        {
            if (!FileExists(filePath))
                return null;

            try
            {
                return new FileInfo(filePath);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to get file info for {filePath}: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 获取目录信息
        /// </summary>
        public static DirectoryInfo GetDirectoryInfo(string path)
        {
            if (!DirectoryExists(path))
                return null;

            try
            {
                return new DirectoryInfo(path);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Failed to get directory info for {path}: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 获取文件的友好大小显示（如：1.5 KB, 2.3 MB等）
        /// </summary>
        public static string GetHumanReadableFileSize(string filePath)
        {
            long size = GetFileSize(filePath);
            if (size < 0)
                return "Unknown";

            return GetHumanReadableFileSizeFromBytes(size);
        }

        /// <summary>
        /// 将字节数转换为友好的大小显示
        /// </summary>
        public static string GetHumanReadableFileSizeFromBytes(long bytes)
        {
            string[] sizes = { "B", "KB", "MB", "GB", "TB" };
            double len = bytes;
            int order = 0;
            while (len >= 1024 && order < sizes.Length - 1)
            {
                order++;
                len = len / 1024;
            }

            // 根据大小调整小数位数
            if (order == 0)
                return $"{bytes} {sizes[order]}";
            else
                return $"{len:0.##} {sizes[order]}";
        }

        #endregion
    }
}